package godzilla.ciudad.administradores;

import godzilla.ciudad.Mapa;
import godzilla.ciudad.Punto;
import godzilla.ciudad.estructuras.Estructura;
import godzilla.ciudad.estructuras.Superficie;
import godzilla.ciudad.recursos.Recurso;

import java.util.Iterator;
import java.util.LinkedList;

public class Administrador {

	public void manejarRecursosEn(Mapa mapa) {

		removerRecursosPropagadosYAsignados(mapa);
		propagarRecursos(mapa);
		asignarRecursos(mapa);
		
		
	}

	private void asignarRecursos(Mapa mapa) {
		
		for(int x=1;x<mapa.dimensionX();x++){
			for(int y=1;y<mapa.dimensionY();y++){
				this.proveerRecursosAEdificioEn(new Punto(x,y), mapa);
			}
		}
		
	}

	private void propagarRecursos(Mapa mapa) {
		
		for(int x=1;x<mapa.dimensionX();x++){
			for(int y=1;y<mapa.dimensionY();y++){
				this.propagarRecursosPorTodoElMapaDesde(new Punto(x,y), mapa);
				this.propagarRadialmenteDesde(new Punto(x,y), mapa);
			}
		}
		
	}

	private void propagarRadialmenteDesde(Punto punto, Mapa mapa) {
		
		
	}

	private void removerRecursosPropagadosYAsignados(Mapa mapa) {

		for(int x=1;x<mapa.dimensionX();x++){
			for(int y=1;y<mapa.dimensionY();y++){
				mapa.verEstructuraEn(new Punto(x,y)).removerRecursosPropagados();
				mapa.verEstructuraEn(new Punto(x,y)).removerRecursosAsignados();
				mapa.verEstructuraSubterraneaEn(new Punto(x,y)).removerRecursosPropagados();
				mapa.verEstructuraSubterraneaEn(new Punto(x,y)).removerRecursosAsignados();
			}
		}
		
	}

	public int recolectarImpuestos(Mapa mapa) {

		int impuestosRecolectados=0;
		
		for(int x=1;x<mapa.dimensionX();x++){
			for(int y=1;y<mapa.dimensionY();y++){
				impuestosRecolectados = impuestosRecolectados + mapa.verEstructuraEn(new Punto(x,y)).recolectarImpuestos();
			}
		}
		
		return impuestosRecolectados;
		
	}
	
	public void propagarRecursosPorTodoElMapaDesde(Punto puntoDeOrigen,Mapa mapa) {

		Superficie superficieOrigen = mapa.verSuperficieEn(puntoDeOrigen);
		Superficie superficieSubterraneaOrigen = mapa.verSuperficieSubterraneaEn(puntoDeOrigen);
		Iterator<Recurso> iterador = superficieOrigen.estructuraContenida().provee().iterador();
		
		while(iterador.hasNext()){
			Recurso recurso = iterador.next();
			propagarRecurso(recurso, superficieOrigen , new LinkedList<Superficie>());
			propagarRecurso(recurso, superficieSubterraneaOrigen , new LinkedList<Superficie>());
		} 
		
		
	}
	

	public void propagarRecursosDesde(Superficie superficieOrigen) {

		Iterator<Recurso> iterador = superficieOrigen.estructuraContenida().provee().iterador();
		
		while(iterador.hasNext()){
			propagarRecurso(iterador.next(), superficieOrigen , new LinkedList<Superficie>());
		} 
		
		
	}

	private void propagarRecurso(Recurso recursoAPropagar, Superficie superficieOrigen , LinkedList<Superficie> superficiesYaRecorridas) {

		Superficie superficieAObservar;
		Iterator<Superficie> iterador = superficieOrigen.verListaDeVecinos().iterator();
		while (iterador.hasNext()){
			superficieAObservar = iterador.next();
		
			if ( !( superficiesYaRecorridas.contains(superficieAObservar) ) ){
				
				superficiesYaRecorridas.add(superficieAObservar);
				if (superficieAObservar.estructuraContenida().permitePropagar(recursoAPropagar)){
					recursoAPropagar.propagar(superficieAObservar.estructuraContenida());
					
					propagarRecurso(recursoAPropagar, superficieAObservar , superficiesYaRecorridas);
				}			
				
			}
		}
		
	}
	
	public void proveerRecursosAEdificioEn(Punto punto , Mapa mapa) {
		
		Superficie superficie = mapa.verSuperficieEn(punto);
		Superficie superficieSubterranea = mapa.verSuperficieSubterraneaEn(punto);
		
		Iterator<Superficie> iterador = superficie.verListaDeVecinos().iterator();
		
		
		//busco recursos en la planta baja
		while(iterador.hasNext()){
			
			Superficie superficieObservada = iterador.next();
			superficie.estructuraContenida().obtenerRecursosDe(superficieObservada.estructuraContenida());
			
		}
		
		
		//busco recursos en el subsuelo
		iterador = superficieSubterranea.verListaDeVecinos().iterator();
		while(iterador.hasNext()){
			
			Superficie superficieObservada = iterador.next();
			superficie.estructuraContenida().obtenerRecursosDe(superficieObservada.estructuraContenida());
			
		}
		
		
	}

	public void proveerRecursosAEdificioEn(Superficie superficie) {
		
		Iterator<Superficie> iterador = superficie.verListaDeVecinos().iterator();
		while(iterador.hasNext()){
			
			Superficie superficieObservada = iterador.next();
			superficie.estructuraContenida().obtenerRecursosDe(superficieObservada.estructuraContenida());
			
		}
		
		
	}

	public void barrerEscombrosEn(Mapa mapa) {
		
		for(int x=1;x<mapa.dimensionX();x++){
			for(int y=1;y<mapa.dimensionY();y++){
				Superficie superficie = mapa.verSuperficieEn(new Punto(x,y));
				if (!superficie.estructuraContenida().enPie()) superficie.destruirEstructura();
			}
		}
		
	}

	public void repararEdificiosEn(Mapa mapa) {
		
		for(int x=1;x<mapa.dimensionX();x++){
			for(int y=1;y<mapa.dimensionY();y++){
				Superficie superficie = mapa.verSuperficieEn(new Punto(x,y));
				Estructura estructura = superficie.estructuraContenida();
				if (estructura.salud() < estructura.saludMaxima()) estructura.repararse();
			}
		}
		
	}


	
}
